////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//                                                                                                                            //
//                                                         WNProject                                                          //
//                                                                                                                            //
//         This file is distributed under the BSD 2-Clause open source license. See Licenses/License.txt for details.         //
//                                                                                                                            //
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#ifndef __WN_SCRIPTING_SCRIPTING_ENGINE_IMPL_H__
#define __WN_SCRIPTING_SCRIPTING_ENGINE_IMPL_H__

#include "WNCore/inc/WNTypes.h"
#include "WNScripting/inc/WNScriptingEngine.h"
#include "WNScripting/inc/WNTypeManager.h"
#include "WNScripting/inc/WNScriptingLog.h"
#include "WNLogging/inc/WNConsoleLogger.h"
#include <vector>
#include <deque>

namespace WNScripting {
    class WNCodeModule;
    struct WNPreprocessedFile;
    class WNScriptingMemoryManager;
    class WNScriptingEngineImpl : public WNScriptingEngine {
    public:
        WNScriptingEngineImpl();
        virtual ~WNScriptingEngineImpl();
        virtual eWNTypeError Initialize();
        virtual eWNTypeError GetFunctionPointer(const WN_CHAR* _file, const WN_CHAR* _functionName, const WNScriptType _retParam, const std::vector<WNScriptType>& _params, void*& _ptr);
        virtual WNScriptType GetTypeByName(const WN_CHAR* _typeName);
        virtual eWNTypeError RegisterFunction(const WN_CHAR* _functionName, const WNScriptType _retParam, const std::vector<WNScriptType>& _params, void* _ptr);
        virtual void* GetRegisteredFunction(const WN_CHAR* _functionName) const;
        virtual void SetInternalLogLevel(WNLogging::WNLogLevel);
        virtual void SetLogLevel(WNLogging::WNLogLevel);
        virtual void SetCompilationLog(WNLogging::WNLog*);
    private:
        static WN_VOID BufferFlushCallback(WN_VOID* _context, const WN_CHAR* buffer, WN_SIZE_T bufferLength, const std::vector<WNLogging::WNLogColorElement>& colors);
        struct WNFunctionRegistry {
            const WN_CHAR* mFunctionName;
            const WN_CHAR* mRegisteredFunctionTag;
            WNScriptType mRetParam;
            std::vector<WNScriptType> mParams;
            void* functionPointer;
        };
        static WN_VOID* CompileLazyFile(WN_VOID* _scriptingEngine, WN_VOID* _requestedFunction);
        eWNTypeError CompileFile(const WN_CHAR* _file, WNCodeModule*& _outModule);
        WNCodeModule* GetCompiledModule(const WN_CHAR* _file);
        eWNTypeError PreprocessFile(const WN_CHAR* _file, WNCodeModule*& _module, WNPreprocessedFile*& _outFile);
        eWNTypeError DumpIntoModule(WNCodeModule*& _module, bool currentFile, WNPreprocessedFile* _preprocessedFile, std::deque<WNPreprocessedFile*>& _nextToProcess);
        eWNTypeError DumpPreprocessedfile(WNCodeModule*& _module, WNPreprocessedFile* _preprocessedFile);
        WNScriptingLogCallback mErrorCallback;
        WNLogging::WNConsoleLogger<> mConsoleLogger;
        WNLogging::WNLog mInternalLogger;
        WNLogging::WNLogLevel mLogLevel;
        WNLogging::WNLog* mCompilationLog;
        std::vector<std::pair<WN_CHAR*, WNCodeModule*> > mFileList;
        std::vector<WNFunctionRegistry> mRegisteredFunctions;
        std::vector<WNPreprocessedFile*> mPreprocessedFiles;
        WNTypeManager* mTypeManager;
        WNScriptingMemoryManager* mMemoryManager;
    };
}
#endif // __WN_SCRIPTING_SCRIPTING_ENGINE_H__
